home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / print / p1123mz4.zip / SQRMAZE.CPP < prev    next >
C/C++ Source or Header  |  1994-02-16  |  25KB  |  622 lines

  1. #include <iostream.h>
  2. #include "oracle.h"
  3. #include "cell.h"
  4. #include "titillat.h"
  5. #include "sqrmaze.h"
  6.  
  7. #define TRUE -1
  8. #define FALSE 0
  9.  
  10. typedef cell *cell_ptr;
  11.  
  12. maze::maze(int row_count,int column_count,int thickness_of_wall,char *seed)
  13. //      Contruct a maze having "row_count" rows and "column_count" columns of
  14. // rooms.  The walls should be "thickness_of_wall" (bricks) thick.  A different
  15. // (8 character of less) "seed" generally yields a different maze.
  16.   {
  17.     struct
  18.       {
  19.          int row_num;
  20.          int column_num;
  21.       }  delta [4];
  22.     int  mud_filled_room_found;
  23.     struct
  24.       {
  25.          int row_num;
  26.          int column_num;
  27.       }  next;
  28.     char wall [24] [4];
  29.     char wall_to_check;
  30.     char wall_num;
  31.     char way_out;
  32.  
  33.     // Allocate a two dimensional array of rooms.
  34.     num_rows=row_count;
  35.     num_columns=column_count;
  36.     if (memory_allocated=((room=new cell_ptr[num_rows]) != NULL))
  37.       {
  38.         int row_num=0;
  39.         while ((memory_allocated) && (row_num < num_rows))
  40.           if (memory_allocated=((room[row_num]=new cell [num_columns]) != NULL))
  41.             row_num++;
  42.         if (! memory_allocated)
  43.           {
  44.             while (row_num)
  45.               delete [] room[--row_num];
  46.             delete [] room;
  47.             cerr << "Fatal error:  cannot allocate maze." << '\n';
  48.           }
  49.       }
  50.     if (memory_allocated)
  51.       {
  52.          wall_thickness=thickness_of_wall;
  53.          // Set up the directions by which a room can be exited.
  54.          delta[0].row_num=-1;    // north
  55.          delta[0].column_num=0;
  56.          delta[1].row_num=0;     // west
  57.          delta[1].column_num=-1;
  58.          delta[2].row_num=1;     // south
  59.          delta[2].column_num=0;
  60.          delta[3].row_num=0;     // east
  61.          delta[3].column_num=1;
  62.          int order_num=0;
  63.          // Set up the 4! orders in which the wall of a room can be accessed.
  64.          for (int wall_num_1=0; wall_num_1 < 4; wall_num_1++)
  65.            for (int wall_num_2=0; wall_num_2 < 4; wall_num_2++)
  66.              if (wall_num_2 != wall_num_1)
  67.                for (int wall_num_3=0; wall_num_3 < 4; wall_num_3++)
  68.                  if ((wall_num_3 != wall_num_2)
  69.                  &&  (wall_num_3 != wall_num_1))
  70.                    for (int wall_num_4=0; wall_num_4 < 4; wall_num_4++)
  71.                      if ((wall_num_4 != wall_num_3)
  72.                      &&  (wall_num_4 != wall_num_2)
  73.                      &&  (wall_num_4 != wall_num_1))
  74.                        {
  75.                          wall[order_num][wall_num_4]='\0';
  76.                          wall[order_num][wall_num_3]='\1';
  77.                          wall[order_num][wall_num_2]='\2';
  78.                          wall[order_num][wall_num_1]='\3';
  79.                          order_num++;
  80.                        }
  81.          titillator_ptr=new titillator;    
  82.          order_selector=new oracle(&seed[0],order_num);
  83.          row_selector=new oracle(&seed[0],num_rows);
  84.          column_selector=new oracle(&seed[0],num_columns); 
  85.          int finished=FALSE;
  86.          // Generate mazes until you have one that is hard to solve.
  87.          do
  88.            {
  89.               // Pick a starting room.
  90.               first.row_num=row_selector->random_number();
  91.               first.column_num=column_selector->random_number();
  92.               current.row_num=first.row_num;
  93.               current.column_num=first.column_num;
  94.               // Excavate the starting room.
  95.               room[current.row_num][current.column_num].mark_floor(' ');
  96.               // Pick the order in which the walls of the starting room will be
  97.               // considered.
  98.               room[current.row_num][current.column_num].set_order(
  99.                order_selector->random_number());
  100.               titillator_ptr->titillate();
  101.               // Excavate rooms until there are no more to excavate.
  102.               do
  103.                 {
  104.                    mud_filled_room_found=FALSE;
  105.                    // Find an adjacent room (not yet considered) that needs
  106.                    // excavating.
  107.                    do
  108.                      {
  109.                         wall_num=room[current.row_num][
  110.                          current.column_num].next_wall_num();
  111.                         if (wall_num < '\4')
  112.                           {
  113.                              wall_to_check=wall[room[current.row_num][
  114.                               current.column_num].order_to_check()][wall_num];
  115.                              if (room[current.row_num][
  116.                               current.column_num].wall_up(wall_to_check))
  117.                                {
  118.                                   next.row_num=current.row_num
  119.                                    +delta[wall_to_check].row_num;
  120.                                   if ((next.row_num >= 0)
  121.                                   &&  (next.row_num < num_rows))
  122.                                     {
  123.                                       next.column_num=current.column_num
  124.                                        +delta[wall_to_check].column_num;
  125.                                       if ((next.column_num >= 0)
  126.                                       &&  (next.column_num < num_columns))
  127.                                         {
  128.                                            if (room[next.row_num][
  129.                                             next.column_num].mark() 
  130.                                             == 'M')
  131.                                              mud_filled_room_found=TRUE;
  132.                                         }
  133.                                     }
  134.                                }
  135.                           }
  136.                      }
  137.                    while ((wall_num < '\4')
  138.                    &&     (! mud_filled_room_found));
  139.                    if (mud_filled_room_found)
  140.                    // an adjacent room needs excavating
  141.                      {
  142.                         // Exit the current room, knocking down a wall.
  143.                         room[current.row_num][
  144.                          current.column_num].knock_down_wall(wall_to_check);
  145.                         way_out=char(((int) wall_to_check+2)%4);
  146.                         // Enter the adjacent room, knocking down a wall.
  147.                         room[next.row_num][next.column_num].knock_down_wall(
  148.                          way_out);
  149.                         // Record how to return to the previous room.
  150.                         room[next.row_num][next.column_num].set_way_out(
  151.                          way_out);
  152.                         current.row_num=next.row_num;
  153.                         current.column_num=next.column_num;
  154.                         // Excavate the room.
  155.                         room[current.row_num][current.column_num].mark_floor(' ');
  156.                         // Select the order in which the walls of the room will
  157.                         // be considered.
  158.                         room[current.row_num][current.column_num].set_order(
  159.                          order_selector->random_number());
  160.                      }
  161.                    else
  162.                    // no adjacent room needs excavating
  163.                      {
  164.                         if ((first.row_num != current.row_num)
  165.                         ||  (first.column_num != current.column_num))
  166.                         // not in starting room
  167.                           {
  168.                              // Go back to the room from which you entered
  169.                              // the current room.
  170.                              next.row_num=current.row_num+delta[
  171.                               room[current.row_num][
  172.                               current.column_num].way_back()].row_num;
  173.                              next.column_num=current.column_num+delta[
  174.                               room[current.row_num][
  175.                               current.column_num].way_back()].column_num;
  176.                              current.row_num=next.row_num;
  177.                              current.column_num=next.column_num;
  178.                           }
  179.                      }
  180.                 }
  181.